package Lono::Fetcher;

# Pragma
use strict;
use warnings;

# Modules and dependencies
use LWP::UserAgent;

use Lono::Fetcher::Client::Epicurious;

=head1 NAME

Lono::Fetcher - Acquires recipes from external sources.

=head1 SYNOPSIS

  use Lono::Fetcher;

  my $fetcher = Lono::Fetcher->new;
  my $response = $fetcher->from_url( 'http://www.epicurious.com/recipes/recipe_views/views/103049' );

  if ( $response->is_success ) {
    my $recipe = $response->get_recipe;
    print $recipe->name;
  }

=cut

# Constants and globals
# XXX: Move to config and make pluggable.
my %LOOKUP_TABLE = 
   (qr{http://([^/]+\.)?epicurious\.com/} => 
        Lono::Fetcher::Client::Epicurious->new);
   

# XXX: Will probably need to allow people to provide their own LWP at 
# some point so I don't have to deal with proxies, etc. 
sub new {
    my $class = shift;
    my $self = {'_lwp' => LWP::UserAgent->new};
    bless $self, $class;
    return $self;
}

sub from_url {
    my ( $self, $url ) = @_;
    my $http_res = $self->{'_lwp'}->get( $url );
    
    # If there's an error, short-circuit 
    unless ( $http_res->is_success ) {
        return $self->_fail( 'error',
               "Could not fetch $url.  LWP reported " . $http_res->status_line);
    }
    
    my $plugin = $self->_dispatch( $url );
    unless ( $plugin ) {
        return $self->_fail( 'error',
               "No plugin registered for $url." ); 
    }

    my $html = $http_res->content;
    my $response = $plugin->handle( $html, $url );

    return $response;
}

sub _dispatch {
    my ( $self, $url ) = @_;
    my $plugin;
    foreach my $pattern ( keys( %LOOKUP_TABLE ) ) {
        if ( $url =~ /$pattern/ ) {
           $plugin = $LOOKUP_TABLE{$pattern};
        }
    }

    return $plugin;
}

sub _fail {
    my ( $self, $severity, $message ) = @_;
    
    my $response = Lono::Fetcher::Response->new;
    $response->add_log_entry( $severity, $message );

    return $response;
}

1;
